package persistence;

import org.hibernate.*;
import org.hibernate.usertype.*;

import java.io.*;
import java.sql.*;
import java.math.*;
import java.util.*;
import hello.*;

public class MonetaryAmountUserType implements UserType
{
	public int[] sqlTypes()
	{
		return new int[]{ Hibernate.BIG_DECIMAL.sqlType(),Hibernate.CURRENCY.sqlType() };
	}
	
	public Class returnedClass()
	{
		return MonetaryAmount.class;
	}
	
	public boolean isMutable()
	{
		return false;
	}
	
	public Object deepCopy(Object value)
	{
		return value;
	}
	
	public Serializable disassemble(Object value)
	{
		return (Serializable)value;
	}
	
	public Object assemble(Serializable cached,Object owner)
	{
		return cached;
	}
	
	public Object replace(Object original,Object target,Object owner)
	{
		return original;
	}
	
	public boolean equals(Object x,Object y)
	{
		if(x == y)
			return true;
		if(x==null || y==null)
			return false;
		return x.equals(y);
	}
	
	public int hashCode(Object x)
	{
		return x.hashCode();
	}
	
	public Object nullSafeGet(ResultSet resultSet,String[] names,Object owner)throws SQLException
	{//how to construct user type
		out("enter nullSafeGet:"+Arrays.asList(names)+"\t"+owner.getClass().getName());
		BigDecimal value =resultSet.getBigDecimal(names[0]);
		Currency c=Currency.getInstance(resultSet.getString(names[1]));
		return new MonetaryAmount(value,c);
	}
	
	public void nullSafeSet(PreparedStatement statement,Object value,int index)throws HibernateException,SQLException
	{//how to persist user type
		if(value==null)
		{
			statement.setNull(index,Hibernate.BIG_DECIMAL.sqlType());
			statement.setNull(index+1,Hibernate.CURRENCY.sqlType());
			//statement.setNull(index,Hibernate.STRING.sqlType());
			out("enter nullSafeSet: set null to parameter:"+index);
		}else
		{
			MonetaryAmount amount=(MonetaryAmount)value;
			statement.setBigDecimal(index,amount.getAmount());
			statement.setString(index+1,amount.getCurrency().getCurrencyCode());
			//out("enter nullSafeSet: bind 555 to parameter:"+index);
		}
	}
	
	void out(Object obj)
	{
		System.out.println(obj.toString());
	}
}